/*******************************************************************************
 * 创建:2025年10月27日
 * 作者:水煮肉片饭（27185709@qq.com）
 * 描述:挖洞组件，可以实现战争迷雾、放大镜、新手引导、转场动画等效果
 * 1、挖洞轮廓支持矩形、椭圆、纹理图采样（类似Mask）
 * 2、可设置挖洞区域位置、大小、边缘羽化。
 * 3、勾选反向（洞内可见洞外透明）后，可以设置洞内像素缩放（放大镜效果）
*******************************************************************************/
import { _decorator, UIRenderer, Component, Enum, js, Material, UITransform, Vec2, NodeEventType, Sprite } from 'cc';
enum Type { 扫光, 转光, 流光 }
const { ccclass, property, disallowMultiple, executeInEditMode, requireComponent, menu } = _decorator;
@ccclass
@disallowMultiple
@executeInEditMode
@requireComponent(UIRenderer)
@menu('Gi/Shader/FlowLight')
class FlowLight extends Component {
    @property({ displayName: '材质', readonly: true })
    materialName: string = '';
    @property
    _type: Type = Type.扫光;
    @property({ displayName: '类型', type: Enum(Type) })
    get type() { return this._type; }
    set type(val) { this._type = val; this.material && this.updateType(); }
    @property
    _strength: number = 1;
    @property({ displayName: '······强度', range: [0, 1, 0.01], slide: true })
    get strength() { return this._strength; }
    set strength(val) { this._strength = val; this.material?.setProperty('strength', val); }
    @property
    _width: number = 100;
    @property({ displayName: '······宽度', visible() { return this._type === Type.扫光 } })
    get width() { return this._width; }
    set width(val) { this._width = val; this.material?.setProperty('width', val); }
    @property
    _angle: number = 0;
    @property({ displayName: '······角度', range: [0, 360], slide: true, visible() { return this._type === Type.扫光 } })
    get angle() { return this._angle; }
    set angle(val) { this._angle = val; this.material?.setProperty('angle', val); }
    @property
    _ratio: number = 0.5;
    @property({ displayName: '······比例', range: [0, 1, 0.01], slide: true, visible() { return this._type === Type.扫光 } })
    get ratio() { return this._ratio; }
    set ratio(val) { this._ratio = val; this.material?.setProperty('ratio', val); }
    @property
    _speed: number = 1;
    @property({ displayName: '······速度', range: [0, 2, 0.01], slide: true, visible() { return this._type !== Type.扫光 } })
    get speed() { return this._speed; }
    set speed(val) { this._speed = val; this.material?.setProperty('speed', val); }
    material: Material = null;
    protected onEnable(): void {
        if (!this.checkMaterial()) return;
        this.material.setProperty('enable', 1);
        this.material.setProperty('strength', this._strength);
        this.updateType();
        this.updateContentSize();
        this.node.on(NodeEventType.SIZE_CHANGED, this.updateContentSize, this);
    }
    protected onDisable(): void {
        this.material['_passes'].length !== 0 && this.material.setProperty('enable', 0);
        this.node.off(NodeEventType.SIZE_CHANGED, this.updateContentSize, this);
    }
    //检测渲染组件的材质，是否与本脚本匹配
    checkMaterial(): boolean {
        let ur = this.node.getComponent(UIRenderer);
        ur['updateMaterial']();
        this.material = ur.getMaterialInstance(0);
        let className = js.getClassName(this);
        this.materialName = ur.customMaterial.name;
        if (this.materialName !== className) {
            console.warn(`节点"${this.node.name}"的组件"${className}.ts"与材质"${this.materialName}.mtl"不匹配！请设置材质为"${className}.mtl"并重新编译！`);
            return false;
        }
        ur instanceof Sprite && ur.spriteFrame && (ur.spriteFrame.packable = false);
        return true;
    }
    updateType(): void {
        this.material.setProperty('type', this._type);
        switch (this._type) {
            case Type.扫光:
                this.material.setProperty('width', this._width);
                this.material.setProperty('angle', this._angle);
                this.material.setProperty('ratio', this._ratio);
                break;
            case Type.转光:
            case Type.流光:
                this.material.setProperty('speed', this._speed);
                break;
        }
    }
    updateContentSize(): void {
        let ut = this.node.getComponent(UITransform);
        this.material.setProperty('texSize', new Vec2(ut.width, ut.height));
    }
}
declare global {
    module gi {
        class FlowLight extends Component {
            static Type: typeof Type;      //类型枚举
            type: Type;                    //类型
            strength: number;              //强度
            width: number;                 //宽度
            angle: number;                 //角度
            ratio: number;                 //比例
            speed: number;                 //速度
        }
    }
}
((globalThis as any).gi ||= {}).FlowLight ||= Object.assign(FlowLight, { Type: Type });